from decimal import Decimal
from django_redis import get_redis_connection
from rest_framework.generics import CreateAPIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

from goods.models import SKU
from orders.serializers import OrderSettlementSerializer, SaveOrderSerializer


class OrderSettlementView(APIView):
    """
    订单结算页面商品视图
    """
    permission_classes = [IsAuthenticated]  # 订单需用户登录

    def get(self, request):
        """
        获取进行结算的商品
        请求方式: GET /orders/settlement/
        请求参数: 无
        返回数据: freight(运费decimal)  skus(结算的商品列表list)  id(商品编号int)  name(商品名称str)  default_image_url(商品默认图片str)  price(商品单价decimal)  count(商品数量int)
        """
        user = request.user

        # 从购物车中获取用户勾选要结算的商品信息
        redis_conn = get_redis_connection('cart')
        # 获取购物车中所有商品,{sku_id: count, ...}
        redis_cart = redis_conn.hgetall('cart_%s' % user.id)
        # 获取商品的勾选记录,存的全是商品id
        cart_selected = redis_conn.smembers('cart_selected_%s' % user.id)

        # 筛选出购物车中所有勾选的商品, redis取出的数据类型是bytes,这里进行类型转换
        cart = {}
        for sku_id in cart_selected:
            cart[int(sku_id)] = int(redis_cart[sku_id])
        # 查询商品信息
        skus = SKU.objects.filter(id__in=cart.keys())
        for sku in skus:
            # 将商品数量存入该商品对象中
            sku.count = cart[sku.id]

        # 运费, 注意,此处只是模拟,实际上需与第三方模块进行管理,不同快递不同地区不同订单/合同导致价格不同,TODO
        freight = Decimal('10.00')

        # 一个订单对应一个运费和一个商品信息表,因此需两层序列化器
        serializer = OrderSettlementSerializer({'freight': freight, 'skus': skus})

        return Response(serializer.data)


class SaveOrderView(CreateAPIView):
    """
    保存订单
    请求方式: POST /orders/
    请求参数: address(收货地址编号int)  pay_method(支付方式int)
    返回数据: order_id(订单编号char)
    """
    permission_classes = [IsAuthenticated]
    serializer_class = SaveOrderSerializer


# 注: 用户中心的订单页面以及首页/详情页的购物车展示未实现 TODO
